package me.yh.tech.dynamic;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.util.Map;

import me.yh.tech.dynamic.service.Service;
import me.yh.tech.util.JavaForm;
import me.yh.tech.util.compiler.JavaStringCompiler;
/**
 * 在静态代码(应用)中定义接口, 动态生成的代码去实现接口(推荐) 动态对象就可以强转为该接口类型, 并调用其相关方法
 *
 * @author liwei
 *
 */
public class App {

	public static String LOCAL_PATH="E:\\CompilerTest";//E:\\CompilerTest /opt/temp/
	public static String LOCAL_NAME="ServiceImpl.java";

	private static final String SOURCE_CODE = "package tech.ldxy.dynamic.service.impl;"
			+ "import tech.ldxy.dynamic.service.Service;"
			/*+ "import com.example.demo.entity.User;"*/
			+ "import java.util.ArrayList;"
			+ "import java.util.List;"
			+ "public class ServiceImpl implements Service {"
			+ "private List list = new ArrayList();"
			/*+ "User user = new User();"*/
			+ "public void start() {" + "System.out.println(\"--- 开启服务 ---\");" + "}" + "public void stop() {"
			+ "System.out.println(\"--- 停止服务 ---\");" + "}" + "}";

	public static void main(String[] args) throws Exception {
		System.out.println("操作系统名称："+System.getProperty("os.name"));
		System.out.println("操作系统架构："+System.getProperty("os.arch"));
		System.out.println("操作系统版本："+System.getProperty("os.version"));
		//	动态加载第三方jar

		// 文件输出到本地
		writeOcrStrtoFile(JavaForm.formJava(SOURCE_CODE), LOCAL_PATH, LOCAL_NAME);
		// 读取本地文件,执行 java 文件
		wreadOcrStrtoFile(LOCAL_PATH, LOCAL_NAME);


	}

	/**
	 * 保存文件到本地
	 * 
	 * @param result
	 * @param outPath
	 * @param outFileName
	 * @throws Exception
	 */
	public static void writeOcrStrtoFile(String result, String outPath, String outFileName) throws Exception {
		File dir = new File(outPath);
		if (!dir.exists()) {
			dir.mkdirs();
		}
		File txt = new File(outPath + "/" + outFileName);
		if (!txt.exists()) {
			txt.createNewFile();
		}
		byte bytes[] = new byte[512];
		bytes = result.getBytes();
		int b = bytes.length; // 是字节的长度，不是字符串的长度
		FileOutputStream fos = new FileOutputStream(txt);
//		fos.write(bytes, 0, b);
		fos.write(bytes);
		fos.flush();
		fos.close();
		System.out.println("写入成功："+txt);
	}

	/**
	 * 读取本地文件
	 *
	 * @param outPath
	 * @param outFileName
	 * @throws Exception
	 */
	public static void wreadOcrStrtoFile(String outPath, String outFileName) throws Exception {
		String path = outPath + "/" + outFileName;
		Object obj = null;
		JavaStringCompiler compiler = new JavaStringCompiler(); // 创建动态编译器
		// 读取本地的java文件
		StringBuffer buffer = new StringBuffer();
		BufferedReader bf = new BufferedReader(new FileReader(path));
		String s = null;
		while ((s = bf.readLine()) != null) {// 使用readLine方法，一次读一行
			//buffer.append(s.trim());
			buffer.append(s.trim());
		}

		String xml = buffer.toString();
		// 关闭流
		bf.close();
		System.out.println("读取到的文件内容:"+xml);
		try {
			// 动态编译 Java 文件, 生成字节码
			Map<String, byte[]> result = compiler.compile("ServiceImpl.java", xml);
			Class<?> clazz = compiler.loadClass("tech.ldxy.dynamic.service.impl.ServiceImpl", result);

			obj = clazz.newInstance(); // 使用反射创建对象

		} catch (Exception ex) {
			ex.printStackTrace();
		}

		if (obj instanceof Service) {
			Service service = (Service) obj;
			service.start();
			service.stop();
		} else {
			System.err.println("对象创建失败。");
		}

	}
}
